package com.twb.system.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.twb.core.base.entity.TwbPageInfo;
import com.twb.core.base.service.impl.BaseService;
import com.twb.core.cache.redis.RedisUtil;
import com.twb.core.exception.ServiceException;
import com.twb.core.util.BeanUtils;
import com.twb.core.util.ExcelUtils;
import com.twb.core.util.TwbPageUtil;
import com.twb.system.entity.twbDataDic.TwbDataDic;
import com.twb.system.entity.twbDataDic.dto.ListTwbDataTypeDto;
import com.twb.system.entity.twbDataDic.dto.SearchTwbDataDicDto;
import com.twb.system.entity.twbDataDic.vo.SaveTwbDataDicVo;
import com.twb.system.entity.twbDataDic.vo.SearchTwbDataDicVo;
import com.twb.system.entity.twbDataDic.vo.UpdateTwbDataDicByIdVo;
import com.twb.system.mapper.TwbDataDicMapper;
import com.twb.system.service.ITwbDataDicService;
import com.twb.system.util.ExcelDataDicHandlerImpl;

/**
 * @ClassName TwbDataDicService
 * @Description 数据字典service
 * 
 * @author DSY
 * @date 2020-11-05 12:54:33
 */
@Service("twbDataDicService")
public class TwbDataDicService extends BaseService<TwbDataDicMapper,TwbDataDic> implements ITwbDataDicService {
	
	@Autowired
	TwbDataDicMapper twbDataDicMapper;

	@Autowired
	RedisUtil redisUtil;

	/*public String getDataName() {
		String cachePrefix = this.twbConfigProperties.getCachePrefix();
		return cachePrefix+":twb_data_name";
	}
	public String getDataValue() {
		String cachePrefix = this.twbConfigProperties.getCachePrefix();
		return cachePrefix+":twb_data_value";
	}*/
	public String getDataDic() {
		String cachePrefix = this.twbConfigProperties.getCachePrefix();
		return cachePrefix+":twb_data_dic";
	}
	@Override
	public boolean initRedisDataDic() {
		
		boolean bl = false;
		TwbPageUtil.orderBy("seq_num asc");
		TwbDataDic record = new TwbDataDic();
		record.setType("1");
		record.setZxbs("0");
		List<TwbDataDic> dataList = this.list(record);

		Map<String, String> dataNameMap = new HashMap<String, String>();
		Map<String, String> dataValueMap = new HashMap<String, String>();
		Map<String, List<TwbDataDic>> dataDicMap = new HashMap<String, List<TwbDataDic>>();

		List<TwbDataDic> temp;

		for (TwbDataDic aa10 : dataList) {
			if (aa10.getZxbs().equals("0")) {
				dataNameMap.put(aa10.getTypeCode() + aa10.getDataValue(), aa10.getDataName());
				dataValueMap.put(aa10.getTypeCode() + aa10.getDataName(), aa10.getDataValue());

				if (dataDicMap.get(aa10.getTypeCode()) != null) {
					dataDicMap.get(aa10.getTypeCode()).add(aa10);
				} else {
					temp = new ArrayList<TwbDataDic>();
					temp.add(aa10);
					dataDicMap.put(aa10.getTypeCode(), temp);
				}
			}
		}

//		redisUtil.set(getDataName(), dataNameMap);
//		redisUtil.set(getDataValue(), dataValueMap);
		redisUtil.set(getDataDic(), dataDicMap);

		bl = true;
		return bl;
	}

	/*@Override
	public Map<String, String> getDataNameMap() {
		Map<String, String> map = redisUtil.get(getDataName());
		if (map == null || map.isEmpty()) {
			boolean init = initRedisDataDic();
			if (init) {
				map = redisUtil.get(getDataName());
			}
		}
		return map;
	}*/

	/*@Override
	public Map<String, String> getDataValueMap() {
		Map<String, String> map = redisUtil.get(getDataValue());
		if (null == map || map.isEmpty()) {
			boolean init = initRedisDataDic();
			if (init) {
				map = redisUtil.get(getDataValue());
			}
		}
		return map;
	}*/

	@Override
	public Map<String, List<TwbDataDic>> getDataDicMap() {
		Map<String, List<TwbDataDic>> map = redisUtil.get(getDataDic());
		if (null == map || map.isEmpty()) {
			boolean init = initRedisDataDic();
			if (init) {
				map = redisUtil.get(getDataDic());
			}
		}
		return map;
	}

	@Override
	public TwbPageInfo<SearchTwbDataDicDto> searchTwbDataDic(SearchTwbDataDicVo vo) {
		TwbPageUtil.startPage(vo);
		List<SearchTwbDataDicDto> list = twbDataDicMapper.searchTwbDataDic(vo);
		return TwbPageUtil.of(list);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int saveTwbDataDic(SaveTwbDataDicVo vo) {
		TwbDataDic param = new TwbDataDic();
		param.setTypeCode(vo.getTypeCode());
		
		if("1".equals(vo.getType())) {
			param.setDataValue(vo.getDataValue());
		}
		long count = this.count(param);
		if (count > 0) {
			throw new ServiceException("该数据字典已存在");
		}
		Integer seqNum = vo.getSeqNum();
		if (seqNum == null) {
			Integer seqNumNew = this.getMaxSeqNumByTypeCode(vo.getTypeCode(), null);
			if (seqNumNew == null) {
				seqNumNew = 1;
			} else {
				seqNumNew = seqNumNew + 1;
			}
			vo.setSeqNum(seqNumNew);
		}
		TwbDataDic record = new TwbDataDic();
		
		BeanUtils.copyNotNullProperties(vo, record);
		
		record.setId(getUUID());
		
		int result = twbDataDicMapper.insert(record);
		if (result > 0) {
			initRedisDataDic();
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int updateTwbDataDicById(UpdateTwbDataDicByIdVo vo) {
		TwbDataDic twbDataDic = this.getById(vo.getId());
		if (null == twbDataDic) {
			throw new ServiceException("数据不存在");
		}
		// 如果typeCode有变更,则更新parentId=该typeCode的字典
		if (vo.getTypeCode() != null && !twbDataDic.getTypeCode().equals(vo.getTypeCode())) {
			TwbDataDic record = new TwbDataDic();
			record.setParentId(twbDataDic.getTypeCode());
			List<TwbDataDic> list = this.list(record);
			if (!list.isEmpty()) {
				for (TwbDataDic dic : list) {
					dic.setParentId(vo.getTypeCode());
				}
				this.updateBatchById(list);
			}
		}

		BeanUtils.copyProperties(vo, twbDataDic);
		int result = twbDataDicMapper.updateById(twbDataDic);
		if (result > 0) {
			initRedisDataDic();
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int deleteTwbDataDicById(String id) {
		int result = twbDataDicMapper.deleteById(id);
		if (result > 0) {
			initRedisDataDic();
		}
		return result;
	}

	@Override
	public int deleteTwbDataDicByIds(String ids) {
		int result = twbDataDicMapper.deleteBatchIds(Arrays.asList(ids.split(",")));
		if (result > 0) {
			initRedisDataDic();
		}
		return result;
	}

	@Override
	public void exportExcel(SearchTwbDataDicVo vo, HttpServletResponse response) throws Exception {

		TwbPageInfo<SearchTwbDataDicDto> pageInfo = this.searchTwbDataDic(vo);
		List<SearchTwbDataDicDto> list = pageInfo.getList();
		ExcelDataDicHandlerImpl diceAddressListHandlerImpl = new ExcelDataDicHandlerImpl();
		String fileName = vo.getFileName();
		if(StringUtils.isBlank(fileName)) {
			fileName="数据字典";
		}
		ExcelUtils.exportExcel(fileName, list, SearchTwbDataDicDto.class, response,diceAddressListHandlerImpl);
	}

	@Override
	public int importExcel(Map<String, String> map) {
		System.out.println(map.toString());
		return 0;
	}

	@Override
	public List<ListTwbDataTypeDto> listTwbDataType(String typeCode, String typeName, String queryWord, String parentId) {
		// TODO Auto-generated method stub
		return twbDataDicMapper.listTwbDataType(typeCode, typeName, queryWord, parentId);
	}

	@Override
	public Integer getMaxSeqNumByTypeCode(String typeCode, String isParent) {
		if (StringUtils.isBlank(isParent)) {
			isParent = "2";
		}
		
		if("null".equals(typeCode)) {
			typeCode = "";
		}
		
		return twbDataDicMapper.getMaxSeqNumByTypeCode(typeCode, isParent);
	}

	@Override
	public List<SearchTwbDataDicDto> searchTwbDataDicTree(SearchTwbDataDicVo vo) {
		// TODO Auto-generated method stub
		List<SearchTwbDataDicDto> list = twbDataDicMapper.searchTwbDataDic(vo);
		return list;
	}

	@Override
	public int updateParentIdByTypeCode(String typeCode, String parentId) {
		TwbDataDic record = new TwbDataDic();
		record.setTypeCode(typeCode);
		List<TwbDataDic> list = this.list(record);
		if (list.isEmpty()) {
			throw new ServiceException("字典类别编码不存在");
		}
		for (TwbDataDic twbDataDic : list) {
			twbDataDic.setParentId(parentId);
		}
		boolean result = this.updateBatchById(list);
		if (result) {
			initRedisDataDic();
			return 1;
		}else {
			return 0;
		}
	}
}
